<html>
<head><meta charset="utf-8"><title>Result/Option enum order · t-compiler · Zulip Chat Archive</title></head>
<h2>Stream: <a href="https://rust-lang.github.io/zulip_archive/stream/131828-t-compiler/index.html">t-compiler</a></h2>
<h3>Topic: <a href="https://rust-lang.github.io/zulip_archive/stream/131828-t-compiler/topic/Result.2FOption.20enum.20order.html">Result/Option enum order</a></h3>

<hr>

<base href="https://rust-lang.zulipchat.com">

<head><link href="https://rust-lang.github.io/zulip_archive/style.css" rel="stylesheet"></head>

<a name="235682314"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/131828-t-compiler/topic/Result/Option%20enum%20order/near/235682314" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Robert Jördens <a href="https://rust-lang.github.io/zulip_archive/stream/131828-t-compiler/topic/Result.2FOption.20enum.20order.html#235682314">(Apr 22 2021 at 13:59)</a>:</h4>
<p>Hello! First post here for me.<br>
When digging a bit deeper into some bad codegen on arm, I started to wonder about the enum ordering and tag values in <code>Option</code> and <code>Result</code>.</p>
<p><code>Result</code> is <code>enum {Ok(T), Err(E)}</code> and <code>Option</code> is <code>enum {None, Some(T)}</code>. Conversions between <code>Result</code> and <code>Option</code> are frequent, as are the methods in the API to do so. But they are much more likely to happen between <code>Ok(T)</code> and <code>Some(T)</code>. This is also supported by the lack of <code>Option::err_or()</code> as the symmetric counterpart to <code>Option::ok_or()</code>. Yet the enum tags of the most common pairing <code>Some(T)</code> and <code>Ok(T)</code> are mismatched and have been for many years (maybe since the beginning). I understand that this looks like an intuitive ordering, but is there a conscious decision behind that?<br>
I know the compiler is free to choose whatever tags it wants, but it doesn't, and why would it ever?</p>
<p>I'm asking specifically because it looks like a hypothetical <code>Option::err_or()</code> would be a bit faster than its counterpart. Or stated differently: Swapping the enum order of either <code>Option</code> or <code>Result</code> appears to be beneficial. This is pretty much universal across targets, optimization and T/E sizes/alignment.</p>
<p><a href="https://godbolt.org/z/ajTdsP6os">https://godbolt.org/z/ajTdsP6os</a></p>
<p>I know it might be a bit pedantic and the benefit isn't gigantic. Still, if there is no technical reason to keep the ordering as it is, why not choose the best ordering?<br>
Does this merit an issue and/or PR on github?</p>



<a name="235682547"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/131828-t-compiler/topic/Result/Option%20enum%20order/near/235682547" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Joshua Nelson <a href="https://rust-lang.github.io/zulip_archive/stream/131828-t-compiler/topic/Result.2FOption.20enum.20order.html#235682547">(Apr 22 2021 at 14:00)</a>:</h4>
<p><span class="user-mention" data-user-id="263076">@Robert Jördens</span> changing the order would change the <code>Ord</code> impl since it's derived</p>



<a name="235682691"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/131828-t-compiler/topic/Result/Option%20enum%20order/near/235682691" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Joshua Nelson <a href="https://rust-lang.github.io/zulip_archive/stream/131828-t-compiler/topic/Result.2FOption.20enum.20order.html#235682691">(Apr 22 2021 at 14:01)</a>:</h4>
<p>which is a very breaking change; insteadyou could implement <code>Ord</code> manually. I'm surprised that the order matters at all for performance though since the layout is unspecified</p>



<a name="235682983"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/131828-t-compiler/topic/Result/Option%20enum%20order/near/235682983" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/131828-t-compiler/topic/Result.2FOption.20enum.20order.html#235682983">(Apr 22 2021 at 14:02)</a>:</h4>
<p>is there a stable way to get the discriminant of an enum?</p>



<a name="235683052"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/131828-t-compiler/topic/Result/Option%20enum%20order/near/235683052" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Joshua Nelson <a href="https://rust-lang.github.io/zulip_archive/stream/131828-t-compiler/topic/Result.2FOption.20enum.20order.html#235683052">(Apr 22 2021 at 14:03)</a>:</h4>
<p><span class="user-mention" data-user-id="271719">@Mario Carneiro</span> <a href="https://doc.rust-lang.org/std/mem/fn.discriminant.html">https://doc.rust-lang.org/std/mem/fn.discriminant.html</a></p>



<a name="235683068"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/131828-t-compiler/topic/Result/Option%20enum%20order/near/235683068" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Joshua Nelson <a href="https://rust-lang.github.io/zulip_archive/stream/131828-t-compiler/topic/Result.2FOption.20enum.20order.html#235683068">(Apr 22 2021 at 14:03)</a>:</h4>
<p>not as an integer though</p>



<a name="235683169"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/131828-t-compiler/topic/Result/Option%20enum%20order/near/235683169" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Joshua Nelson <a href="https://rust-lang.github.io/zulip_archive/stream/131828-t-compiler/topic/Result.2FOption.20enum.20order.html#235683169">(Apr 22 2021 at 14:03)</a>:</h4>
<p>I think that's to allow the size of the discriminant to be unspecified</p>



<a name="235683173"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/131828-t-compiler/topic/Result/Option%20enum%20order/near/235683173" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/131828-t-compiler/topic/Result.2FOption.20enum.20order.html#235683173">(Apr 22 2021 at 14:03)</a>:</h4>
<p>ah, and it doesn't implement <code>Ord</code>, smart</p>



<a name="235683272"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/131828-t-compiler/topic/Result/Option%20enum%20order/near/235683272" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Robert Jördens <a href="https://rust-lang.github.io/zulip_archive/stream/131828-t-compiler/topic/Result.2FOption.20enum.20order.html#235683272">(Apr 22 2021 at 14:04)</a>:</h4>
<p><span class="user-mention" data-user-id="232545">@Joshua Nelson</span> I see. But still, why is the ordering (e.g. <code>Err(0) &gt; Ok(99)</code>) as it is? Just coincidence?</p>



<a name="235683323"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/131828-t-compiler/topic/Result/Option%20enum%20order/near/235683323" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/131828-t-compiler/topic/Result.2FOption.20enum.20order.html#235683323">(Apr 22 2021 at 14:04)</a>:</h4>
<p>It does implement <code>Hash</code> though, which might change</p>



<a name="235683600"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/131828-t-compiler/topic/Result/Option%20enum%20order/near/235683600" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/131828-t-compiler/topic/Result.2FOption.20enum.20order.html#235683600">(Apr 22 2021 at 14:06)</a>:</h4>
<p><span class="user-mention" data-user-id="263076">@Robert Jördens</span> Even if it is entirely incidental, it's impossible to know if people are relying on it since that's a stable part of the API of the type</p>



<a name="235685919"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/131828-t-compiler/topic/Result/Option%20enum%20order/near/235685919" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Robert Jördens <a href="https://rust-lang.github.io/zulip_archive/stream/131828-t-compiler/topic/Result.2FOption.20enum.20order.html#235685919">(Apr 22 2021 at 14:18)</a>:</h4>
<p>So something for Rust 2.0 ;)</p>



<a name="235686015"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/131828-t-compiler/topic/Result/Option%20enum%20order/near/235686015" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Joshua Nelson <a href="https://rust-lang.github.io/zulip_archive/stream/131828-t-compiler/topic/Result.2FOption.20enum.20order.html#235686015">(Apr 22 2021 at 14:19)</a>:</h4>
<p>realistically rust 2.0 is not going to happen</p>
<p><span class="user-mention" data-user-id="263076">@Robert Jördens</span> do you mind expanding on why changing the declaration order changes codegen? I wouldn't expect that.</p>



<a name="235686341"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/131828-t-compiler/topic/Result/Option%20enum%20order/near/235686341" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Robert Jördens <a href="https://rust-lang.github.io/zulip_archive/stream/131828-t-compiler/topic/Result.2FOption.20enum.20order.html#235686341">(Apr 22 2021 at 14:21)</a>:</h4>
<p>See the godbolt MWE, compare <code>some_to_err</code> and <code>some_to_ok</code>. When converting <code>Some(T)</code> to <code>Err(T)</code>, it doesn't need to change the enum tag. For <code>some_to_ok</code> it does.</p>



<a name="235687308"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/131828-t-compiler/topic/Result/Option%20enum%20order/near/235687308" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Joshua Nelson <a href="https://rust-lang.github.io/zulip_archive/stream/131828-t-compiler/topic/Result.2FOption.20enum.20order.html#235687308">(Apr 22 2021 at 14:26)</a>:</h4>
<p>that seems like something we should fix in the compiler, not in libstd</p>



<a name="235687402"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/131828-t-compiler/topic/Result/Option%20enum%20order/near/235687402" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Robert Jördens <a href="https://rust-lang.github.io/zulip_archive/stream/131828-t-compiler/topic/Result.2FOption.20enum.20order.html#235687402">(Apr 22 2021 at 14:27)</a>:</h4>
<p>The effect is most significant on arm/thumb and smaller on nightly/x86.</p>



<a name="235689186"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/131828-t-compiler/topic/Result/Option%20enum%20order/near/235689186" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Robert Jördens <a href="https://rust-lang.github.io/zulip_archive/stream/131828-t-compiler/topic/Result.2FOption.20enum.20order.html#235689186">(Apr 22 2021 at 14:37)</a>:</h4>
<p>Then one take home message is that eagerly deriving traits "where it makes sense" (as recommended in best practices), can lead to somewhat "accidental" stabilization.</p>



<a name="235690038"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/131828-t-compiler/topic/Result/Option%20enum%20order/near/235690038" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Robert Jördens <a href="https://rust-lang.github.io/zulip_archive/stream/131828-t-compiler/topic/Result.2FOption.20enum.20order.html#235690038">(Apr 22 2021 at 14:42)</a>:</h4>
<p>How is <code>Ord</code> derived/implemented if not through the <code>Discriminant</code>?</p>



<a name="235690044"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/131828-t-compiler/topic/Result/Option%20enum%20order/near/235690044" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Robert Jördens <a href="https://rust-lang.github.io/zulip_archive/stream/131828-t-compiler/topic/Result.2FOption.20enum.20order.html#235690044">(Apr 22 2021 at 14:42)</a>:</h4>
<p><span class="user-mention" data-user-id="232545">@Joshua Nelson</span> I don't feel qualified to push this further. I'm happy to leave it if the impact isn't deemed significant enough or if it's unlikely to go anywhere. What should I do?</p>



<a name="235690150"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/131828-t-compiler/topic/Result/Option%20enum%20order/near/235690150" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Joshua Nelson <a href="https://rust-lang.github.io/zulip_archive/stream/131828-t-compiler/topic/Result.2FOption.20enum.20order.html#235690150">(Apr 22 2021 at 14:43)</a>:</h4>
<p>I would look into why the compiler generates different code; is it making different layout decisions somewhere?</p>



<a name="235690186"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/131828-t-compiler/topic/Result/Option%20enum%20order/near/235690186" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Joshua Nelson <a href="https://rust-lang.github.io/zulip_archive/stream/131828-t-compiler/topic/Result.2FOption.20enum.20order.html#235690186">(Apr 22 2021 at 14:43)</a>:</h4>
<p>it seems weird for layout to depend on order but i'm not familiar with that part of the compiler</p>



<a name="235690227"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/131828-t-compiler/topic/Result/Option%20enum%20order/near/235690227" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Joshua Nelson <a href="https://rust-lang.github.io/zulip_archive/stream/131828-t-compiler/topic/Result.2FOption.20enum.20order.html#235690227">(Apr 22 2021 at 14:43)</a>:</h4>
<p><span class="user-mention" data-user-id="123586">@nagisa</span> may have ideas</p>



<a name="235690706"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/131828-t-compiler/topic/Result/Option%20enum%20order/near/235690706" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Joshua Nelson <a href="https://rust-lang.github.io/zulip_archive/stream/131828-t-compiler/topic/Result.2FOption.20enum.20order.html#235690706">(Apr 22 2021 at 14:46)</a>:</h4>
<p>also I would make sure this <em>is</em> actually affected by order - have you tried your godbolt example with a modified version of the standard library?</p>



<a name="235690712"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/131828-t-compiler/topic/Result/Option%20enum%20order/near/235690712" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Robert Jördens <a href="https://rust-lang.github.io/zulip_archive/stream/131828-t-compiler/topic/Result.2FOption.20enum.20order.html#235690712">(Apr 22 2021 at 14:46)</a>:</h4>
<p>I think the effect comes about because <code>Some(T)</code> and <code>Err(T)</code> end up having the exact same representation including numerical value of the discriminant, making conversion easy.</p>



<a name="235690901"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/131828-t-compiler/topic/Result/Option%20enum%20order/near/235690901" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Robert Jördens <a href="https://rust-lang.github.io/zulip_archive/stream/131828-t-compiler/topic/Result.2FOption.20enum.20order.html#235690901">(Apr 22 2021 at 14:47)</a>:</h4>
<p>I haven't but then I'd rather compare my own <code>SwappedResult</code> to a copy of stdlib's <code>Result</code>.</p>



<a name="235692317"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/131828-t-compiler/topic/Result/Option%20enum%20order/near/235692317" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Lokathor <a href="https://rust-lang.github.io/zulip_archive/stream/131828-t-compiler/topic/Result.2FOption.20enum.20order.html#235692317">(Apr 22 2021 at 14:56)</a>:</h4>
<p>The source ordering matters because any given type doesn't magically look at the layout of other types when determining its own layout.</p>
<p>So while it's better overall for Ok/Some and Err/None to be a match, the compiler <strong>doesn't know</strong> this, and just goes with the "good enough by default" ordering used for all enums of following the ordering written in the source (unless, of course, the monomorph causes a better layout to become obvious, eg: Option&lt;NonNull&gt; uses the niche, etc etc).</p>
<p>And yes, the ordering is unspecified, but there is still <em>some ordering</em> that the compiler has to pick, and this is how the compiler currently picks it.</p>



<a name="235694041"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/131828-t-compiler/topic/Result/Option%20enum%20order/near/235694041" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Robert Jördens <a href="https://rust-lang.github.io/zulip_archive/stream/131828-t-compiler/topic/Result.2FOption.20enum.20order.html#235694041">(Apr 22 2021 at 15:03)</a>:</h4>
<p><a href="https://godbolt.org/z/Yoe8vjqTx">https://godbolt.org/z/Yoe8vjqTx</a> to show that this is source ordering.</p>



<a name="235694643"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/131828-t-compiler/topic/Result/Option%20enum%20order/near/235694643" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Robert Jördens <a href="https://rust-lang.github.io/zulip_archive/stream/131828-t-compiler/topic/Result.2FOption.20enum.20order.html#235694643">(Apr 22 2021 at 15:05)</a>:</h4>
<p><span class="user-mention" data-user-id="224471">@Lokathor</span> Then ordering is unspecified in the compiler but at the same time well-defined and stabilized by the library?</p>



<a name="235694736"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/131828-t-compiler/topic/Result/Option%20enum%20order/near/235694736" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Joshua Nelson <a href="https://rust-lang.github.io/zulip_archive/stream/131828-t-compiler/topic/Result.2FOption.20enum.20order.html#235694736">(Apr 22 2021 at 15:06)</a>:</h4>
<p><span class="user-mention" data-user-id="263076">@Robert Jördens</span> the <em>layout</em> is not stabilized, the <code>Ord</code> impl is</p>



<a name="235694784"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/131828-t-compiler/topic/Result/Option%20enum%20order/near/235694784" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Joshua Nelson <a href="https://rust-lang.github.io/zulip_archive/stream/131828-t-compiler/topic/Result.2FOption.20enum.20order.html#235694784">(Apr 22 2021 at 15:06)</a>:</h4>
<p>they are different</p>



<a name="235694852"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/131828-t-compiler/topic/Result/Option%20enum%20order/near/235694852" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Joshua Nelson <a href="https://rust-lang.github.io/zulip_archive/stream/131828-t-compiler/topic/Result.2FOption.20enum.20order.html#235694852">(Apr 22 2021 at 15:06)</a>:</h4>
<p>like I said before, you can change the source order if you add a custom <code>Ord</code> impl</p>



<a name="235694902"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/131828-t-compiler/topic/Result/Option%20enum%20order/near/235694902" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Lokathor <a href="https://rust-lang.github.io/zulip_archive/stream/131828-t-compiler/topic/Result.2FOption.20enum.20order.html#235694902">(Apr 22 2021 at 15:06)</a>:</h4>
<p>if the source was changed but the ord impl written by hand to ensure the old ordering that could be merged to stable, for example</p>



<a name="235694937"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/131828-t-compiler/topic/Result/Option%20enum%20order/near/235694937" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Lokathor <a href="https://rust-lang.github.io/zulip_archive/stream/131828-t-compiler/topic/Result.2FOption.20enum.20order.html#235694937">(Apr 22 2021 at 15:06)</a>:</h4>
<p>yes what josh said</p>



<a name="235695029"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/131828-t-compiler/topic/Result/Option%20enum%20order/near/235695029" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Robert Jördens <a href="https://rust-lang.github.io/zulip_archive/stream/131828-t-compiler/topic/Result.2FOption.20enum.20order.html#235695029">(Apr 22 2021 at 15:07)</a>:</h4>
<p>I see.</p>



<a name="235695775"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/131828-t-compiler/topic/Result/Option%20enum%20order/near/235695775" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Robert Jördens <a href="https://rust-lang.github.io/zulip_archive/stream/131828-t-compiler/topic/Result.2FOption.20enum.20order.html#235695775">(Apr 22 2021 at 15:10)</a>:</h4>
<p>But the merit of that approach would then hinge on unspecified compiler behavior.</p>



<a name="235695854"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/131828-t-compiler/topic/Result/Option%20enum%20order/near/235695854" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Joshua Nelson <a href="https://rust-lang.github.io/zulip_archive/stream/131828-t-compiler/topic/Result.2FOption.20enum.20order.html#235695854">(Apr 22 2021 at 15:10)</a>:</h4>
<p>well yes, unless you hard-code Option in the compiler the layout will always be unspecified</p>



<a name="235700849"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/131828-t-compiler/topic/Result/Option%20enum%20order/near/235700849" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> nagisa <a href="https://rust-lang.github.io/zulip_archive/stream/131828-t-compiler/topic/Result.2FOption.20enum.20order.html#235700849">(Apr 22 2021 at 15:43)</a>:</h4>
<p>hash of discriminant is not guaranteed to be stable across compilations with different toolchain versions, its called out in the description of the <a href="https://doc.rust-lang.org/stable/std/mem/fn.discriminant.html"><code>discriminant</code></a> function.</p>



<a name="235700993"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/131828-t-compiler/topic/Result/Option%20enum%20order/near/235700993" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> nagisa <a href="https://rust-lang.github.io/zulip_archive/stream/131828-t-compiler/topic/Result.2FOption.20enum.20order.html#235700993">(Apr 22 2021 at 15:44)</a>:</h4>
<p>Specifying more sensible discriminants for variants also makes sense to me, especially now that (IIRC) there's an ability to actually explicitly specify the discriminants of non-c-like enums.</p>



<a name="235701020"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/131828-t-compiler/topic/Result/Option%20enum%20order/near/235701020" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> nagisa <a href="https://rust-lang.github.io/zulip_archive/stream/131828-t-compiler/topic/Result.2FOption.20enum.20order.html#235701020">(Apr 22 2021 at 15:44)</a>:</h4>
<p>the only requirement here is that <code>None</code> stays <code>0</code>.</p>



<a name="235705471"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/131828-t-compiler/topic/Result/Option%20enum%20order/near/235705471" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> cuviper <a href="https://rust-lang.github.io/zulip_archive/stream/131828-t-compiler/topic/Result.2FOption.20enum.20order.html#235705471">(Apr 22 2021 at 16:15)</a>:</h4>
<p>why would <code>None</code> always be <code>0</code>? for <code>Option&lt;File&gt;</code> it should use the <code>-1</code> niche</p>



<a name="235707046"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/131828-t-compiler/topic/Result/Option%20enum%20order/near/235707046" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> scottmcm <a href="https://rust-lang.github.io/zulip_archive/stream/131828-t-compiler/topic/Result.2FOption.20enum.20order.html#235707046">(Apr 22 2021 at 16:26)</a>:</h4>
<p><span class="user-mention silent" data-user-id="263076">Robert Jördens</span> <a href="#narrow/stream/131828-t-compiler/topic/Result.2FOption.20enum.20order/near/235682314">said</a>:</p>
<blockquote>
<p>Still, if there is no technical reason to keep the ordering as it is, why not choose the best ordering?<br>
Does this merit an issue and/or PR on github?</p>
</blockquote>
<p>Here's a PR from 2018 that tried to do just that:<br>
<a href="https://github.com/rust-lang/rust/pull/49499">https://github.com/rust-lang/rust/pull/49499</a></p>
<p>AFAIK the current explorations around this are trying to add MIR opts to fix some of these suboptimalities in rustc, since LLVM historically has been bad at doing it.  See the pass <a href="https://github.com/rust-lang/rust/blob/25c15cdbe070f49d708f34750df2632e38bd4846/compiler/rustc_mir/src/transform/simplify_try.rs#L1-L10">https://github.com/rust-lang/rust/blob/25c15cdbe070f49d708f34750df2632e38bd4846/compiler/rustc_mir/src/transform/simplify_try.rs#L1-L10</a> for example.</p>



<a name="235707273"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/131828-t-compiler/topic/Result/Option%20enum%20order/near/235707273" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> scottmcm <a href="https://rust-lang.github.io/zulip_archive/stream/131828-t-compiler/topic/Result.2FOption.20enum.20order.html#235707273">(Apr 22 2021 at 16:28)</a>:</h4>
<p><span class="user-mention silent" data-user-id="138448">cuviper</span> <a href="#narrow/stream/131828-t-compiler/topic/Result.2FOption.20enum.20order/near/235705471">said</a>:</p>
<blockquote>
<p>why would <code>None</code> always be <code>0</code>? for <code>Option&lt;File&gt;</code> it should use the <code>-1</code> niche</p>
</blockquote>
<p>I don't think that it's <em>always</em> zero, but that <code>[Option&lt;ThingWithoutNiche&gt;; N]</code> should always be readable from an all-zeroes page, rather than needing to embed extra constants for it.</p>



<a name="235707970"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/131828-t-compiler/topic/Result/Option%20enum%20order/near/235707970" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Robert Jördens <a href="https://rust-lang.github.io/zulip_archive/stream/131828-t-compiler/topic/Result.2FOption.20enum.20order.html#235707970">(Apr 22 2021 at 16:32)</a>:</h4>
<p>I think I have to retract my claim that swapping the <code>Result</code> enum order is generally beneficial.<br>
On current nightly it looks like this only comes about in the hypothetical <code>Option&lt;E&gt;::err_or(T) -&gt; Result&lt;T, E&gt;</code> if that <code>T</code> value has certain structure. On 1.51.0 it is a significant difference.<br>
On the other hand the swapped <code>Result</code> is also never worse.<br>
Thank you all for the input!</p>
<p>I still think <code>Option&lt;E&gt;::err_or(T) -&gt; Result&lt;T, E&gt;</code> would make the API more symmetric though.</p>



<a name="235708451"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/131828-t-compiler/topic/Result/Option%20enum%20order/near/235708451" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Robert Jördens <a href="https://rust-lang.github.io/zulip_archive/stream/131828-t-compiler/topic/Result.2FOption.20enum.20order.html#235708451">(Apr 22 2021 at 16:35)</a>:</h4>
<p><span class="user-mention silent" data-user-id="125270">scottmcm</span> <a href="#narrow/stream/131828-t-compiler/topic/Result.2FOption.20enum.20order/near/235707046">said</a>:</p>
<blockquote>
<p>Here's a PR from 2018 that tried to do just that:<br>
<a href="https://github.com/rust-lang/rust/pull/49499">https://github.com/rust-lang/rust/pull/49499</a></p>
</blockquote>
<p>Ah. Yes! I had seen that a couple days ago but couldn't find it when looking for it. Looks like the <code>Result</code> swap PR never materialized.</p>



<a name="235710177"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/131828-t-compiler/topic/Result/Option%20enum%20order/near/235710177" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> nagisa <a href="https://rust-lang.github.io/zulip_archive/stream/131828-t-compiler/topic/Result.2FOption.20enum.20order.html#235710177">(Apr 22 2021 at 16:47)</a>:</h4>
<p><span class="user-mention silent" data-user-id="138448">cuviper</span> <a href="#narrow/stream/131828-t-compiler/topic/Result.2FOption.20enum.20order/near/235705471">said</a>:</p>
<blockquote>
<p>why would <code>None</code> always be <code>0</code>? for <code>Option&lt;File&gt;</code> it should use the <code>-1</code> niche</p>
</blockquote>
<p>Ah, well, so <code>None</code> has to retain unspecified discriminant, and <code>Some</code> can't have a specified one because it might end up inhabiting a specific niche of some type that could otherwise utilize the optimization (which we don't guarantee other than for <code>NonZero</code> IIRC?)</p>



<a name="235710902"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/131828-t-compiler/topic/Result/Option%20enum%20order/near/235710902" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/131828-t-compiler/topic/Result.2FOption.20enum.20order.html#235710902">(Apr 22 2021 at 16:51)</a>:</h4>
<p>In the presence of niche optimizations, I don't think discriminant numbers mean anything. The discriminant numbers only matter when using the "standard" tag + data layout for an enum</p>



<a name="235712320"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/131828-t-compiler/topic/Result/Option%20enum%20order/near/235712320" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Robert Jördens <a href="https://rust-lang.github.io/zulip_archive/stream/131828-t-compiler/topic/Result.2FOption.20enum.20order.html#235712320">(Apr 22 2021 at 17:00)</a>:</h4>
<p>What's the difference between tag and discriminant?</p>



<a name="235713938"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/131828-t-compiler/topic/Result/Option%20enum%20order/near/235713938" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/131828-t-compiler/topic/Result.2FOption.20enum.20order.html#235713938">(Apr 22 2021 at 17:09)</a>:</h4>
<p>I don't know how common the convention is, but I would say that the discriminant is the logical integer associated to the variants, i.e. the first variant has discriminant 0, the second 1 and so on, unless they are overridden with <code>= n</code>; while the tag is the portion of the concrete layout in a tag + union. The tag will always be the same as the discriminant if it exists, but if there is a niche optimization there might not be a tag field, but the discriminant still logically exists, encoded in some bit patterns</p>



<a name="235714120"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/131828-t-compiler/topic/Result/Option%20enum%20order/near/235714120" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/131828-t-compiler/topic/Result.2FOption.20enum.20order.html#235714120">(Apr 22 2021 at 17:10)</a>:</h4>
<p>but mind you I'm just making this up, they are largely interchangeable</p>



<hr><p>Last updated: Aug 07 2021 at 22:04 UTC</p>
</html>